import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter_socket_client/permission_utils.dart';
import 'package:flutter_socket_client/qrscan_page.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_socket_client/screen_util.dart';
import 'custom_icon_button.dart';
import 'package:share_extend/share_extend.dart';
import 'package:flutter_socket_client/scan_util.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: <String, WidgetBuilder>{
        // 其中/a代表页面a
        '/a': (BuildContext context) => MyApp(),
        '/b': (BuildContext context) => QRScanPage(),
      },
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  static const STORAGE_PATH = '/storage/emulated/0/Download/test.zip';

  Socket mClientSocket;
  num mHasTransLength = 0;
  num mTargetFileLength = 0;
  File mStorageFile;
  int mCurrentProgress;
  int mLastProgress;

  void _incrementCounter() {
    PermissionUtil.requestStorage();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            NiIconButton(
              onTap: () async {
                ScanUtil.parseScan();
                var result = await Navigator.pushNamed(context, '/b');
                if (result != null) {
                  extractParams(result);
                }
              },
              child: Image.asset(
                'assets/icon/qr.png',
                width: 20.w,
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  Future<void> extractParams(String result) async {
    print("result:$result");
    List<String> str = result.split(":");
    await connect(str[0], int.parse(str[1]));
  }

  Future<void> dataHandler(Uint8List data) async {
    final request = String.fromCharCodes(data);
    if (request.startsWith("second handle")) {
      if (Platform.isAndroid) {
        mStorageFile = File(STORAGE_PATH);
      } else if (Platform.isIOS) {
        Directory appDocDir = await getApplicationDocumentsDirectory();
        String appDocPath = appDocDir.path + '/test.zip';
        mStorageFile = File(appDocPath);
      }

      if (mStorageFile.existsSync()) {
        mStorageFile.deleteSync();
      }
      print("main,二次握手成功");
      List<String> secondHandle = request.split(":");
      mHasTransLength = 0;
      mTargetFileLength = int.parse(secondHandle[1]);
      print("main,(4),maxLength:$mTargetFileLength");
      mClientSocket.write('third handle,ok');
      print("main,发起三次握手");
      return;
    }
    print('main,(5),接收到数据长度:${data.lengthInBytes}');
    await handleData(data);
    mHasTransLength += data.lengthInBytes;
    if (mHasTransLength >= mTargetFileLength) {
      print("main,接收数据完毕");
      double progress = 100 * mHasTransLength / mTargetFileLength;
      print(
          "main,(7)__length:$mHasTransLength,maxLength:$mTargetFileLength,receive progress:$progress");
      await Future.delayed(Duration(seconds: 1));
      _closeSocket();
      if (Platform.isIOS) {
        ShareExtend.share(mStorageFile.path, "file");
      }
    } else {
      mCurrentProgress = (100 * mHasTransLength ~/ mTargetFileLength).toInt();
      if (mCurrentProgress != mLastProgress) {
        print(
            "main,(6)__length:$mHasTransLength,maxLength:$mTargetFileLength,receive progress:$mCurrentProgress");
      }
      mLastProgress = mCurrentProgress;
    }
  }

  void errorHandler(error, StackTrace trace) {
    mClientSocket.write('closed');
    print("(7)__Error: ");
  }

  void doneHandler() {
    mClientSocket.destroy();
    print("(8)__socket.destroy:  $mHasTransLength");
  }

  Future<void> _closeSocket() async {
    print("(9)__socket.prints");
    mClientSocket.close();
    print("main:_socket.close()");
    mClientSocket.destroy();
  }

  Future<void> connect(String serverIp, int serverPort) async {
    await Socket.connect(serverIp, serverPort).then((Socket sock) {
      mClientSocket = sock;
      mClientSocket.write('first handle,I want you Send Data');
      print("(4)__socket.write: Socket sends data to database");
      mClientSocket.listen(dataHandler,
          onError: errorHandler, onDone: doneHandler, cancelOnError: true);
    });
  }

  List<int> toIntList(Uint8List source) {
    return List.from(source);
  }

  Future<void> handleData(Uint8List data) async {
    if (Platform.isAndroid) {
      await Permission.storage.request().isGranted;
    }
    mStorageFile.writeAsBytesSync(data, mode: FileMode.append, flush: true);
  }
}
